package com.yeung.actions;

import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import static com.yeung.actions.ServiceResult.SUCCESS;

/**
 * 使用ExceptionHandler 注解
 * 或者ControllerAdvice 实现该功能
 */
@Controller()
@RequestMapping("/error")
public class ExceptionTest {
    @RequestMapping("/test")
    public void test(@RequestParam("i") Integer i) {
        System.out.println("error id=" + i);
        System.out.println(10 / i);
    }

    /**
     * 处理异常
     *
     * @return
     */
    @ExceptionHandler
    public ModelAndView handException(Exception e, ModelMap map) {
        System.out.println("出异常了");
        //将异常带到错误页面进行展示
        //不能使用modelMap携带数据过去, 无效,需要使用modelView
        ModelAndView andView = new ModelAndView("error");
        andView.addObject("exception", e);
        return andView;
    }

    /**
     * 处理指定的异常
     * 异常匹配度越高,优先级越高
     * <p>
     * 如果当前handler 中找不到@ExceptionHandler 注解标记的方法来处理当前异常,
     * * 则去@ControllerAdvice标记的类中寻找@ExceptionHandler标记的方法来处理异常
     *
     * @param e
     * @param map
     * @return
     */
    @ExceptionHandler({RuntimeException.class})
    public ModelAndView handException2(Exception e, ModelMap map) {
        System.out.println("出异常了");
        //将异常带到错误页面进行展示
        //不能使用modelMap携带数据过去, 无效,需要使用modelView
        ModelAndView andView = new ModelAndView("error");
        andView.addObject("exception", e);
        return andView;
    }

    @ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "用户名和密码不匹配")
    @RequestMapping("/testResponseStatus")
    public void testResponseStatus() {

    }

    @RequestMapping("/testSimpleMappingExceptionResolver")
    public String testSimpleMappingExceptionResolver(@RequestParam("id") int id) {
        System.out.println("testSimpleMappingExceptionResolver...");
        String[] val = new String[10];
        System.out.println(val[id]);
        return SUCCESS;
    }
}

/**
 * 自定义切面控制类,来实现异常捕获
 * 如果当前handler 中找不到@ExceptionHandler 注解标记的方法来处理当前异常,
 * * 则去@ControllerAdvice标记的类中寻找@ExceptionHandler标记的方法来处理异常
 */
@ControllerAdvice
class GloablExceptionHandler {
    @ExceptionHandler({ArithmeticException.class})
    public ModelAndView handException2(Exception e, ModelMap map) {
        System.out.println("出异常了");
        //将异常带到错误页面进行展示
        //不能使用modelMap携带数据过去, 无效,需要使用modelView
        ModelAndView andView = new ModelAndView("error");
        andView.addObject("exception", e);
        return andView;
    }
}

/**
 * @ResponseStatus 指定一个类的响应的状态码和响应信息
 * 以可以用于方法上
 */
@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "用户名和密码不匹配")
class UserNameNotMatchException extends RuntimeException {

}
